<template>
  <div class="default-main page">
    <PageSearch
      ref="pageSearchRef"
      :pageName="pageName"
      :searchConfig="searchConfigComputed"
    ></PageSearch>
    <PageContent
      ref="pageContentRef"
      :pageName="pageName"
      :contentConfig="contentConfigComputed"
      :autoDesc="false"
      :dictMap="dictMap"
      :tableListener="tableListener"
      :tableSelected="tableSelected"
      :permission="permission"
      :requestBaseUrl="requestBaseUrl"
      :tableHideItems="tableHideItems"
      :idKey="'userId'"
      @beforeSend="beforeSend"
      @addClick="addClick"
      @editBtnClick="editBtnClick"
      @onChangeShowColumn="onChangeShowColumn"
      @deleteClick="handleDelete"
      @editMoreClick="editMoreClick"
    >
      <template #handleLeft>
        <el-button
          type="warning"
          class="ml12 order16"
          v-hasPermi="['system:users:export']"
          @click="handleExport"
        >
          <SvgIcon size="14" iconClass="download" />
          <span class="ml6">导出</span>
        </el-button>
        </template>
      <template #avatarSlot="{ backData }">
        <el-avatar 
          size="small" 
          :src="getAvatarUrl(backData.avatar)" 
          @error="() => true">
          <el-icon><UserFilled /></el-icon>
        </el-avatar>
        </template>
      <template #statusSlot="{ backData }">
        <el-switch
          v-model="backData.status"
          active-value="0"
          inactive-value="1"
          @click="handleStatusChange(backData)"
          :loading="backData.statusLoading"
        ></el-switch>
        </template>
    </PageContent>
    <PageDialog
      ref="dialogRef"
      :width="getWidth(dialogWidth)"
      :pageName="pageName"
      :dialogConfig="dialogConfigComputed"
      :infoInit="infoInit"
      :search="search"
      :isEditMore="isEditMore"
      :requestBaseUrl="requestBaseUrl"
      @editNext="editNext"
      @beforeCommit="handleBeforeCommit"
    >
      <template #avatarCustom="{ backData }">
        <avatar-upload
          v-model="backData.formData[backData.item.field]"
          :userId="backData.formData.userId"
          @success="(url) => backData.formData[backData.item.field] = url"
        />
      </template>
    </PageDialog>
  </div>
</template>

<script setup name="Users">
import { nextTick } from 'vue'
import { listUsers, getUsers, delUsers, addUsers, updateUsers, uploadUsersAvatar } from "@/api/system/users"
import useDialog from '@/hooks/useDialog'
import getComputedConfig from '@/hooks/getPageConfig'
import { inject } from 'vue'
import to from '@/utils/to'
import { systemBaseUrl } from '@/api/config/base.js'
import getSearchConfig from './config/searchConfig'
import getContentConfig from './config/contentConfig'
import getDialogConfig from './config/dialogConfig'
import { UserFilled } from '@element-plus/icons-vue'
import AvatarUpload from './components/AvatarUpload.vue'
import { encrypt } from '@/utils/jsencrypt'
import businessStore from '@/store/business/businessStore'

const proxy = inject('proxy')
const { sys_normal_disable } = proxy.useDict('sys_normal_disable')

const pageName = 'users'
const requestBaseUrl = systemBaseUrl
const pageSearchRef = ref(null)
const pageContentRef = ref(null)
const xhOperationsList = ref([])

const dialogHideItems = ref([])
const tableHideItems = ref([])
const dictMap = {
  status: sys_normal_disable
}
const searchConfig = getSearchConfig()
const searchConfigComputed = computed(() => {
  return getComputedConfig(searchConfig, dictMap)
})
const tableSelected = ref([])
const tableListener = {
  selectionChange: (selected) => {
    tableSelected.value = selected
  },
}
const contentConfig = getContentConfig()
const contentConfigComputed = computed(() => {
  contentConfig.hideItems = tableHideItems
  return contentConfig
})

const dialogConfig = getDialogConfig()

const dialogConfigComputed = computed(() => {
  dialogConfig.hideItems = dialogHideItems
  return getComputedConfig(dialogConfig, dictMap)
})

const addCallBack = () => {
  dialogHideItems.value = ['userId']
}

const editCallBack = (item, type, res) => {
  dialogHideItems.value = ['userId']
  // 不再隐藏密码字段，允许编辑时显示密码
  isEditMore.value = type
}

const isEditMore = ref(false)
const editMoreClick = () => {
  if (tableSelected.value.length > 0) {
    const data = tableSelected.value[0]
    pageContentRef.value?.editClick(data, true)
    nextTick(() => {
      const newArray = tableSelected.value.slice(1)
      dialogRef.value?.changeSelected(newArray)
    })
  }
}

const editNext = (data) => {
  pageContentRef.value?.editClick(data, true)
}

// 提交表单前的处理
const handleBeforeCommit = (form) => {
  // 这里可以对表单进行预处理
  if (form.xhOperationsList && form.xhOperationsList.length === 0) {
    delete form.xhOperationsList
  }
  
  // 处理密码字段
  if (form.password) {
    // 如果有密码，对密码进行加密
    try {
      // 记住表单中显示的明文密码
      const plaintextPassword = form.password
      // 加密密码用于提交到后端
      form.password = encrypt(plaintextPassword)
      
      // 保存新创建的用户的明文密码，仅用于显示
      if (!form.userId) {
        sessionStorage.setItem('lastCreatedUserPassword', plaintextPassword)
      }
    } catch (error) {
      console.error('密码加密失败', error)
      proxy.$modal.msgError('密码加密失败，请重试')
      return false // 阻止表单提交
    }
  } else if (form.userId) {
    // 如果是编辑模式且密码为空，则不提交密码字段，保留原密码
    delete form.password
  }
  
  return form
}

// 添加用户完成的回调
const handleAddSuccess = (res) => {
  if (res.code === 200) {
    // 获取刚才保存的明文密码
    const password = sessionStorage.getItem('lastCreatedUserPassword')
    if (password) {
      // 显示成功信息和密码
      proxy.$modal.msgSuccess(`用户创建成功！账号密码为：${res.data.username || res.data.user?.username} / ${password}`)
      // 清除存储的密码
      sessionStorage.removeItem('lastCreatedUserPassword')
    } else {
      proxy.$modal.msgSuccess('用户创建成功！')
    }
    // 刷新列表
    search()
  } else {
    proxy.$modal.msgError(res.msg || '创建失败')
  }
}

// 覆盖store的createDataAction方法，添加成功回调
const storeInstance = businessStore()
const originalCreateDataAction = storeInstance.createDataAction
storeInstance.createDataAction = async (payload) => {
  // 如果是用户创建操作
  if (payload.pageName === pageName) {
    const res = await originalCreateDataAction(payload)
    if (res.code === 200) {
      handleAddSuccess(res)
    }
    return res
  }
  // 其他操作使用原始方法
  return await originalCreateDataAction(payload)
}

const [dialogRef, infoInit, addClick, editBtnClick] = useDialog(
  addCallBack,
  editCallBack,
  '添加'
)

const dialogWidth = ref('600px')
const searchData = computed(() => {
  return pageContentRef.value?.finalSearchData
})

const search = () => {
  pageSearchRef.value?.search()
}

const beforeSend = (queryInfo) => {
  if (queryInfo.dateRange && Array.isArray(queryInfo.dateRange)) {
    const dateRange = queryInfo.dateRange
    queryInfo['params[beginTime]'] = dateRange[0]
    queryInfo['params[endTime]'] = dateRange[1]
    delete queryInfo.dateRange
  }
}

const handleStatusChange = async (row) => {
  row.statusLoading = true
  let text = row.status === '0' ? '启用' : '停用'
  try {
    const [res, err] = await to(updateUsers(row))
    if (res) {
      proxy.$modal.msgSuccess(text + '成功')
      } else {
      row.status = row.status === '0' ? '1' : '0'
      proxy.$modal.msgError(err.message || text + '失败')
    }
  } catch (error) {
    row.status = row.status === '0' ? '1' : '0'
    proxy.$modal.msgError(error.message || text + '失败')
  }
  row.statusLoading = false
}

// 删除用户
const handleDelete = async (row) => {
  const userIds = Array.isArray(row) ? row.map(item => item.userId) : row.userId
  if (!userIds || (Array.isArray(userIds) && userIds.length === 0)) {
    proxy.$modal.msgError('未获取到有效Id')
    return
  }
  
  proxy.$modal.confirm(`确认删除用户编号为"${userIds}"的数据项？`).then(async () => {
    const [res, err] = await to(delUsers(userIds))
    if (res) {
      proxy.$modal.msgSuccess('删除成功')
      search()
  } else {
      proxy.$modal.msgError(err.message || '删除失败')
    }
  }).catch(() => {})
}

const permission = ref({
  add: 'system:users:add',
  edit: 'system:users:edit',
  del: 'system:users:remove',
})
const onChangeShowColumn = (filterArr) => {
  tableHideItems.value = filterArr
}

/** 导出按钮操作 */
const handleExport = () => {
  proxy.download(
    'system/users/export',
    {
      ...searchData.value,
    },
    `users_${new Date().getTime()}.xlsx`
  )
}

// 获取头像完整URL
const getAvatarUrl = (avatar) => {
  if (!avatar) return ''
  return avatar.startsWith('http') ? avatar : (import.meta.env.VITE_APP_BASE_API + avatar)
}
</script>

<style scoped lang="scss">
.page {
  :deep(.statusClass .el-radio-group) {
    width: 100%;
    justify-content: space-between;
    .el-radio {
      margin-right: 0;
    }
  }
}
</style>
